<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>S3QL::Object - High-level object-like perl interface to the S3DB API</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:" />
</head>

<body style="background-color: white">

<p><a name="__index__"></a></p>
<!-- INDEX BEGIN -->

<ul>

	<li><a href="#name">NAME</a></li>
	<li><a href="#synopsis">SYNOPSIS</a></li>
	<li><a href="#description">DESCRIPTION</a></li>
	<ul>

		<li><a href="#setup">Setup</a></li>
		<li><a href="#searching_for_objects">Searching for Objects</a></li>
		<li><a href="#reading_objects">Reading Objects</a></li>
		<li><a href="#creating_objects">Creating Objects</a></li>
		<li><a href="#getting_the_statements_about_an_object">Getting the Statements about an Object</a></li>
		<li><a href="#printing_objects">Printing Objects</a></li>
		<li><a href="#exporting_as_xml">Exporting as XML</a></li>
		<li><a href="#saving_objects">Saving Objects</a></li>
	</ul>

	<li><a href="#uploading_files">Uploading Files</a></li>
	<li><a href="#debugging">Debugging</a></li>
	<ul>

		<li><a href="#implementation_details">Implementation Details</a></li>
	</ul>

</ul>
<!-- INDEX END -->

<hr />
<p>
</p>
<h1><a name="name">NAME</a></h1>
<p>S3QL::Object - High-level object-like perl interface to the S3DB API</p>
<p>
</p>
<hr />
<h1><a name="synopsis">SYNOPSIS</a></h1>
<pre>
 <span class="keyword">require</span> <span class="variable">S3QL::Object</span><span class="operator">;</span>
 <span class="variable">S3QL::Object::setup</span><span class="operator">(</span><span class="string">key</span> <span class="operator">=&gt;</span> <span class="variable">$key</span><span class="operator">,</span> <span class="string">host</span> <span class="operator">=&gt;</span> <span class="variable">$host</span><span class="operator">);</span>
 <span class="variable">S3QL::Object::setup</span><span class="operator">(</span><span class="string">key</span> <span class="operator">=&gt;</span> <span class="variable">$key</span><span class="operator">,</span> <span class="string">host</span> <span class="operator">=&gt;</span> <span class="variable">$host</span><span class="operator">,</span> <span class="string">projectID</span> <span class="operator">=&gt;</span> <span class="variable">$pid</span><span class="operator">);</span>
 <span class="variable">S3QL::Object::setProject</span><span class="operator">(</span><span class="variable">$pid</span><span class="operator">);</span>
</pre>
<pre>
 <span class="keyword">my</span> <span class="variable">@resourceIds</span> <span class="operator">=</span> <span class="variable">S3QL::Object::lookup</span><span class="operator">(</span><span class="variable">$entity</span><span class="operator">);</span>
 <span class="keyword">my</span> <span class="variable">@resourceIds</span> <span class="operator">=</span> <span class="variable">S3QL::Object::lookup</span><span class="operator">(</span><span class="variable">$entity</span><span class="operator">,</span> <span class="operator">{</span><span class="variable">$property</span> <span class="operator">=&gt;</span> <span class="variable">$value</span><span class="operator">}</span><span class="operator">);</span>
</pre>
<pre>
 <span class="keyword">my</span> <span class="variable">$object</span> <span class="operator">=</span> <span class="variable">new</span> <span class="variable">S3QL::Object</span><span class="operator">(</span><span class="operator">{</span><span class="string">entity</span> <span class="operator">=&gt;</span> <span class="variable">$type</span><span class="operator">,</span> <span class="string">resource_id</span> <span class="operator">=&gt;</span> <span class="variable">$rid</span><span class="operator">}</span><span class="operator">);</span>
 <span class="keyword">foreach</span> <span class="keyword">my</span> <span class="variable">$rid</span> <span class="operator">(</span><span class="variable">@resourceIDs</span><span class="operator">)</span> <span class="operator">{</span>
    <span class="keyword">my</span> <span class="variable">$object</span> <span class="operator">=</span> <span class="variable">new</span> <span class="variable">S3QL::Object</span><span class="operator">(</span><span class="operator">{</span><span class="string">entity</span> <span class="operator">=&gt;</span><span class="string">"Folder"</span><span class="operator">,</span> <span class="string">resource_id</span> <span class="operator">=&gt;</span> <span class="variable">$rid</span><span class="operator">}</span><span class="operator">);</span>
    <span class="comment"># do something with the object ...</span>
 <span class="operator">}</span>
</pre>
<pre>
 <span class="keyword">my</span> <span class="variable">@stms</span> <span class="operator">=</span> <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">statements</span><span class="operator">();</span>
</pre>
<pre>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">show</span><span class="operator">;</span>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">show</span><span class="operator">(\</span><span class="variable">*STDOUT</span><span class="operator">);</span>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">show</span><span class="operator">(</span><span class="variable">$fh</span><span class="operator">);</span>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">asXML</span><span class="operator">;</span>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">asXML</span><span class="operator">(</span><span class="variable">$fh</span><span class="operator">);</span>
</pre>
<pre>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">save</span><span class="operator">;</span>
</pre>
<pre>
 <span class="variable">S3QL::Object::debug</span><span class="operator">(</span><span class="variable">$level</span><span class="operator">);</span>
</pre>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>This class provides a high-level interface to the S3DB API described
at <a href="http://www.s3db.org">http://www.s3db.org</a>; the interface is built upon lower level 
structures described in the packages <em>RawS3QL</em>  and <em>S3QL</em>.  The main
idea is to create an object-like interface that unites a resource (or 
instance) together with all the statements about that resource into
a single perl object.</p>
<p>It is important to note at the outset that the <code>S3QL::Object</code> makes a critical
simplifying assumption about the underlying semantic database.  The general
semantic web technology as implemented in S3DB is built on rules of the form 
'subject verb object', where both 'subject' and 'object' are instances of a
defined class. So, some system might include both of the following rules:</p>
<pre>
 PERSON owns CAR
 PERSON drives CAR</pre>
<p>where the two verbs ('owns' and 'drives') represent two different relationships
between the subject (a PERSON) and the object (a CAR). Many simple (and useful)
semantic structures, however, have the property that at most one relationship
holds between any given <strong>type</strong> of subject and object.  In this case, the appropriate rule
describing the relationship can be computed if you know the class of the subject
and the class of the object.  The <code>S3QL::Object</code> package assumes that it is living
in this simpler world, which makes possible an implementation using very simple
data structures.</p>
<p>
</p>
<h2><a name="setup">Setup</a></h2>
<p>In order to create, read, update, or destroy objects, you must have
access to a deployment of an S3DB database where the objects live. In
order to obtain this access programmatically, you must specify the host
server and an access key.  In the <code>S3QL::Object</code> class, you do this using
the <code>setup</code> function:</p>
<pre>
 <span class="variable">S3QL::Object::setup</span><span class="operator">(</span><span class="string">key</span> <span class="operator">=&gt;</span> <span class="variable">$key</span><span class="operator">,</span> <span class="string">host</span> <span class="operator">=&gt;</span> <span class="variable">$host</span><span class="operator">);</span>
 <span class="variable">S3QL::Object::setup</span><span class="operator">(</span><span class="string">key</span> <span class="operator">=&gt;</span> <span class="variable">$key</span><span class="operator">,</span> <span class="string">host</span> <span class="operator">=&gt;</span> <span class="variable">$host</span><span class="operator">,</span> <span class="string">projectID</span> <span class="operator">=&gt;</span> <span class="variable">$pid</span><span class="operator">);</span>
</pre>
<p>For demonstration purposes, the package uses a key for a guest account
at a default host at M.D. Anderson.  You can deploy your own host by
downloading the S3DB source from <a href="http://www.s3db.org">http://www.s3db.org</a>.  Instructions
at the same location explain how to create user accounts and how to
create access keys.</p>
<p>The items stored in an S3DB database are organized into projects. The
underlying model used by <code>S3QL::Object</code> assumes that you are only 
interested in the objects from a single project.  You can optionally
supply the numerical identifier of the project to the <code>setup</code> function.
Alternatively, you can specify the project ID later using the
<code>setProject</code> function:</p>
<pre>
 <span class="variable">S3QL::Object::setProject</span><span class="operator">(</span><span class="variable">$pid</span><span class="operator">);</span>
</pre>
<p>You can either use the web interface to your deployment of S3DB to
determine the project ID, or you can use a <code>select</code> statement in the
<em>S3QL</em> package to get a list of project names and IDs.</p>
<p>
</p>
<h2><a name="searching_for_objects">Searching for Objects</a></h2>
<p>You can use the <code>lookup</code> function to get a list of the resource IDs of
objects of a given type.  For example, to get a list of all resources
whose S3DB class is <code>'Type'</code>, you would use the command:</p>
<pre>
 <span class="keyword">my</span> <span class="variable">@resourceIds</span> <span class="operator">=</span> <span class="variable">S3QL::Object::lookup</span><span class="operator">(</span><span class="string">'Type'</span><span class="operator">);</span>
</pre>
<p>You can also search for objects of a given type by specifying some of
their  properties. For example, suppose the S3DB project contains objects
of type <code>'Folder'</code> or type <code>'File'</code>, and that one of the basic rules 
in the database is <code>'File' 'belongs-to' 'Folder'</code>.  Suppose further that
you know the resource ID (<code>$fid</code>) of a particular <code>'Folder'</code> and
want to find all of the <code>'File'</code> objects in that <code>'Folder'</code>.  Then
you would write:</p>
<pre>
 <span class="keyword">my</span> <span class="variable">@resourceIds</span> <span class="operator">=</span> <span class="variable">S3QL::Object::lookup</span><span class="operator">(</span><span class="string">'File'</span><span class="operator">,</span> <span class="operator">{</span><span class="string">'Folder'</span> <span class="operator">=&gt;</span> <span class="variable">$fid</span><span class="operator">}</span><span class="operator">);</span>
</pre>
<p><strong>Remark:</strong> As mentioned above, the <code>S3QL::Object</code> package assumes that the 
types of the subject and object together fully determine the rule that
connects them, which is the only reason this syntax works to look up objects.</p>
<p>
</p>
<h2><a name="reading_objects">Reading Objects</a></h2>
<p>Once you have a resource ID in hand, you can read an object from the S3DB
database. The simplest way do achieve this goal is to write</p>
<pre>
 <span class="keyword">my</span> <span class="variable">$object</span> <span class="operator">=</span> <span class="variable">new</span> <span class="variable">S3QL::Object</span><span class="operator">(</span><span class="operator">{</span><span class="string">entity</span> <span class="operator">=&gt;</span> <span class="variable">$type</span><span class="operator">,</span> <span class="string">resource_id</span> <span class="operator">=&gt;</span> <span class="variable">$rid</span><span class="operator">}</span><span class="operator">);</span>
</pre>
<p>If you have already used the <code>lookup</code> function to get a list of IDs, then
a common idiom is to loop over the list constructing individual objects:</p>
<pre>
 <span class="keyword">foreach</span> <span class="keyword">my</span> <span class="variable">$rid</span> <span class="operator">(</span><span class="variable">@resourceIDs</span><span class="operator">)</span> <span class="operator">{</span>
    <span class="keyword">my</span> <span class="variable">$object</span> <span class="operator">=</span> <span class="variable">new</span> <span class="variable">S3QL::Object</span><span class="operator">(</span><span class="operator">{</span><span class="string">entity</span> <span class="operator">=&gt;</span><span class="string">"Folder"</span><span class="operator">,</span> <span class="string">resource_id</span> <span class="operator">=&gt;</span> <span class="variable">$rid</span><span class="operator">}</span><span class="operator">);</span>
    <span class="comment"># do something with the object ...</span>
 <span class="operator">}</span>
</pre>
<p>
</p>
<h2><a name="creating_objects">Creating Objects</a></h2>
<p>You also use the <code>new S3QL::Object</code> method to create a new object that is not
yet stored in the database. In this case, you pass in a hash that defines
the properties of the object you are trying to create:</p>
<pre>
 <span class="keyword">my</span> <span class="variable">$object</span> <span class="operator">=</span> <span class="variable">new</span> <span class="variable">S3QL::Object</span><span class="operator">(</span><span class="operator">{</span><span class="string">entity</span> <span class="operator">=&gt;</span> <span class="variable">$type</span><span class="operator">,</span> <span class="variable">$prop1</span> <span class="operator">=&gt;</span> <span class="variable">$value1</span><span class="operator">,</span> <span class="operator">...</span><span class="operator">}</span><span class="operator">);</span>
</pre>
<p><strong>Remark:</strong> As mentioned above, the <code>S3QL::Object</code> package assumes that the 
types of the subject and object together fully determine the rule that
connects them, which is the only reason this syntax works to create
objects.  Also, since this is supposed to be a new object, you should not
include a value for the <code>resource_id</code> component of the hash.</p>
<p>
</p>
<h2><a name="getting_the_statements_about_an_object">Getting the Statements about an Object</a></h2>
<p>Regardless of where the object comes from you, can get a list of all the
statements about the object by invoking</p>
<pre>
 <span class="keyword">my</span> <span class="variable">@stms</span> <span class="operator">=</span> <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">statements</span><span class="operator">();</span>
</pre>
<p>The return value from this function is a list of hash references. Each hash
will contain values for</p>
<ol>
<li>
<p><code>rule_id</code>, the numerical ID of the rule that describes the structure
of this statement.</p>
</li>
<li>
<p><code>subject</code>, the subject of the rule, which should match the S3DB class
of the <code>$object</code> on which the method was invoked. (It is sometimes 
hard to keep the subjects and objects straight....)</p>
</li>
<li>
<p><code>verb</code>, the verb that describes the relation represented by the rule.</p>
</li>
<li>
<p><code>object</code>, the class of the object of the rule.</p>
</li>
<li>
<p><code>value</code>, the actual value taken on by the object of the rule in this
particular statement.</p>
</li>
<li>
<p><code>created_on</code>, the date (and time, separated by a space) when the statement
was made.</p>
</li>
</ol>
<p>
</p>
<h2><a name="printing_objects">Printing Objects</a></h2>
<pre>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">show</span><span class="operator">;</span>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">show</span><span class="operator">(\</span><span class="variable">*STDOUT</span><span class="operator">);</span>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">show</span><span class="operator">(</span><span class="variable">$fh</span><span class="operator">);</span>
</pre>
<p>The <code>show</code> method will print the object as a string. By default, the string is
printed to STDERR, which is useful in debugging. More generally, you can pass a
reference to a file handle into the function, and the string will be printed 
there instead.</p>
<p><strong>Important Note:</strong> Two of the keys inside the object hash are special: 
<code>statements</code> and <code>data</code>.  The <code>statements</code> key is a reference to an array of
statement IDs that identify the S3DB statements that enumerate this objects
properties. The <code>data</code> key is a reference to a hash that contains the items
that were used to initialize the object.</p>
<p>
</p>
<h2><a name="exporting_as_xml">Exporting as XML</a></h2>
<pre>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">asXML</span><span class="operator">;</span>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">asXML</span><span class="operator">(</span><span class="variable">$fh</span><span class="operator">);</span>
</pre>
<p>The <code>asXML</code> method serializes the object in an XML file. As with <code>show</code>,
the default is to print the XML to STDERR, but you can supply a file handle
if you want to send it somewhere else.</p>
<p>
</p>
<h2><a name="saving_objects">Saving Objects</a></h2>
<pre>
 <span class="variable">$object</span><span class="operator">-&gt;</span><span class="variable">save</span><span class="operator">;</span>
</pre>
<p>New objects can be saved (inserted into the S3DB database) using the <code>save</code>
method. For efficiency, an object remembers if it is new (to the database)
and whether it has been changed since being read from the database.  The
package should allow you to save both new objects and edited objects. <em>At
present, saving edited objects that were read from the database is not yet
implemented.</em></p>
<p>
</p>
<hr />
<h1><a name="uploading_files">Uploading Files</a></h1>
<p>The <code>uploadFile</code> function is a front end to the function with the same
name in the <em>S3QL</em> package. It takes one of the forms</p>
<pre>
 <span class="variable">S3QL::Object::uploadFile</span><span class="operator">(</span><span class="variable">$filename</span><span class="operator">,</span> <span class="variable">$resourceID</span><span class="operator">,</span> <span class="variable">$ruleID</span><span class="operator">,</span> <span class="variable">$notes</span><span class="operator">);</span>
 <span class="variable">S3QL::Object::uploadFile</span><span class="operator">(</span><span class="variable">$filename</span><span class="operator">,</span> <span class="variable">$resourceID</span><span class="operator">,</span> <span class="variable">$ruleID</span><span class="operator">,</span> <span class="variable">$notes</span><span class="operator">,</span> <span class="variable">$fh</span><span class="operator">);</span>
</pre>
<p>In the latter form, you explicitly pass in a file handle from which the file
should be read, and the <code>$filename</code> argument is simply treated as a character
string that should be used as the name of the file in the S3DB database.  If
the file handle argument is omitted, then the <code>$filename</code> must be the actual
name of a file on the local file system that should be uploaded. This design
decision was dictated by the need to support file upload boxes in CGI web pages,
where the browser handles the upload to the web server and provides a file 
handle, and the file must then be further tranported to the S3DB server.</p>
<p>
</p>
<hr />
<h1><a name="debugging">Debugging</a></h1>
<p>Because of the somewhat complicated nature of this package, which builds on two 
lower levels to create an object-like interface to a semantic web database, there
are lots of places where it will (optionally) write useful information to STDERR.
You can set the level of output by</p>
<pre>
 <span class="variable">S3QL::Object::debug</span><span class="operator">(</span><span class="variable">$level</span><span class="operator">);</span>
</pre>
<p>Larger values of <code>$level</code> produce more output. Once upon a time, there was a
system to the levels, but that system has succumbed to the powers of entropy. At
present, setting the level equal to 10 gets you all the debugging information
that the package provides.</p>
<p>
</p>
<h2><a name="implementation_details">Implementation Details</a></h2>
<p>In order to speed things up, the package maintains a cache of the S3DB classes,
rules, instances, and statements in memory.  You can use the functions</p>
<pre>
 <span class="variable">S3QL::Object::printClasses</span><span class="operator">();</span>
 <span class="variable">S3QL::Object::printRules</span><span class="operator">();</span>
 <span class="variable">S3QL::Object::printInstances</span><span class="operator">();</span>
</pre>
<p>to print a complete list of classes, rules, or instances to STDERR. There is
no separate function to print the statements, since the <code>printInstances</code>
function prints all the statements associated with each instance. These
functions are provided primarily with a view to their usefulness in debugging
routines that use the package.</p>

</body>

</html>
